package br.com.beans;

import java.util.List;

import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Transient;

import br.com.dao.UsuarioDAO;

/** Classe que representa um usuario do sistema  */
@Entity
@Table(name="tb_usuario")
public class Usuario {

	/** Um usuario pode ser administrador, atendente ou medico */
	public static enum Nivel {
		ADMINISTRADOR, ATENDENTE, MEDICO
	}

	/** Nome de login (username) do usuario */
	@Id
	@Column(length=15,nullable=false)
	private String userName;

	/** Senha do usuario */ 
	@Column(length=15,nullable=false)
	private String senha;
	
	/** Nome do usuario */
	@Column(length=50,nullable=false)
	private String nome;
	
	/** Nivel de acesso do usuario */
	@Column(nullable=false)
	private Nivel nivel = Nivel.ATENDENTE;
	
	/** Nova senha (para realizar alteracao). */
	@Transient
	private String novaSenha;
	
	/** Construtor padrao */
	public Usuario() {}

	/** Construtor de copia */
	public Usuario(Usuario usuario) {
		copiar(usuario);
	}

	/** Limpa todos atributos. */
	public void limpar() {
		setUserName(null);
		setSenha(null);
		setNome(null);
		setNivel(Nivel.ATENDENTE);
	}
	
	/** Copia atributos de outro objeto.
	 *  @param obj Objeto a ser copiado */
	public void copiar(Usuario obj) {
		if (obj != null) {
			setUserName(obj.getUserName());
			setSenha(obj.getSenha());
			setNome(obj.getNome());
			setNivel(obj.getNivel());
		} else {
			limpar();
		}
	}
	
	/** Valida um usuario.
	  * @return String representando a pagina destino no faces. */
	public String validar() {
		UsuarioDAO usuarioDAO = new UsuarioDAO();
		FacesMessage facesMessage = null;  
		
		Usuario usuario = usuarioDAO.validar(getUserName(), getSenha());
		copiar(usuario);

		if (usuario == null) {
			facesMessage = new FacesMessage("Erro: Nome de Usuario e/ou Senha invalidos.",null);  
			FacesContext.getCurrentInstance().addMessage(null,facesMessage);
			return ""; 
		} else if (usuario.isAdmin()) {
			return "menuAdm";
		} else if (usuario.isAtendente()) {
			return "menuAtendente";
		} else if (usuario.isMedico()) {
			return "menuMedico";
		} else {
			facesMessage = new FacesMessage("Erro: Nivel de acesso do usuario desconhecido.",null);  
			FacesContext.getCurrentInstance().addMessage(null,facesMessage);
			return ""; 
		}
	}
	
	/** Altera a senha do usuario logado.
	  * @return String representando a pagina destino no faces. */
	public String alterarSenha() {
		UsuarioDAO usuarioDAO = new UsuarioDAO();
		FacesMessage facesMessage = null;  

		if (usuarioDAO.alterarSenha(getUserName(),novaSenha)) {
			setSenha(novaSenha);
			facesMessage = new FacesMessage("Senha alterada com sucesso.",null);  
		} else {
			facesMessage = new FacesMessage("Erro ao alterar senha.",null);  
		}
		setNovaSenha(null);
		FacesContext.getCurrentInstance().addMessage(null,facesMessage);
		return "";
	}

	/** Faz "logoff" do usuario.
	  * @return String representando a pagina destino no faces. */
	public String invalidar() {
		limpar();
		return "login";
	}

	/** Cadastra um atendente. */
	public void cadastrarAtendente() {
		UsuarioDAO usuarioDAO = new UsuarioDAO();
		FacesMessage facesMessage = null;  

		setSenha(getUserName());
		setNivel(Nivel.ATENDENTE);
		
		if (usuarioDAO.inserir(this)) {
			facesMessage = new FacesMessage("Atendente adicionado com sucesso.",null);  
			limpar();
		} else {
			facesMessage = new FacesMessage("Erro ao adicionar atendente.",null);  
		}
		FacesContext.getCurrentInstance().addMessage(null,facesMessage);  
	}

	/** Cadastra um administrador. */
	public void cadastrarAdmin() {
		UsuarioDAO usuarioDAO = new UsuarioDAO();
		FacesMessage facesMessage = null;  
		
		setSenha(getUserName());
		setNivel(Nivel.ADMINISTRADOR);
		
		if (usuarioDAO.inserir(this)) {
			facesMessage = new FacesMessage("Administrador adicionado com sucesso.",null);  
			limpar();
		} else {
			facesMessage = new FacesMessage("Erro ao adicionar administrador.",null);  
		}
		FacesContext.getCurrentInstance().addMessage(null,facesMessage);  
	}

	/** Remove um usuario. */
	public void remover() {
		UsuarioDAO usuarioDAO = new UsuarioDAO();
		FacesMessage facesMessage = null;  

		if (usuarioDAO.excluir(getUserName())) {
			facesMessage = new FacesMessage("Usuario removido com sucesso.",null);  
		} else {
			facesMessage = new FacesMessage("Erro ao remover usuario.",null);  
		}
		limpar();
		FacesContext.getCurrentInstance().addMessage(null,facesMessage);  
	}
	
	/** Retorna uma lista de atendentes.
	 * @return Lista de atendentes. */
	public List<Usuario> getListaAtendente() {
		UsuarioDAO usuarioDAO = new UsuarioDAO();
		return usuarioDAO.listar(Nivel.ATENDENTE);
	}
	
	/** Retorna uma lista de administradores.
	 * @return Lista de administradores. */
	public List<Usuario> getListaAdmin() {
		UsuarioDAO usuarioDAO = new UsuarioDAO();
		return usuarioDAO.listar(Nivel.ADMINISTRADOR);
	}
	
	/** Retorna true se o usuario tem nivel de administrador */
	public boolean isAdmin() {
		return (nivel == Nivel.ADMINISTRADOR);
	}
	
	/** Retorna true se o usuario tem nivel de atendente */
	public boolean isAtendente() {
		return (nivel == Nivel.ATENDENTE);
	}

	/** Retorna true se o usuario tem nivel de medico */
	public boolean isMedico() {
		return (nivel == Nivel.MEDICO);
	}

	/** Retorna o nivel como um valor inteiro */
	public int getNivelAsInt() {
		return nivel.ordinal();
	}
	
	public String getUserName() {
		return userName;
	}

	public void setUserName(String userName) {
		this.userName = userName;
	}

	public String getSenha() {
		return senha;
	}

	public void setSenha(String senha) {
		this.senha = senha;
	}

	public String getNome() {
		return nome;
	}

	public void setNome(String nome) {
		this.nome = nome;
	}

	public void setNivel(Nivel nivel) {
		this.nivel = nivel;
	}

	public Nivel getNivel() {
		return nivel;
	}

	public String getNovaSenha() {
		return novaSenha;
	}

	public void setNovaSenha(String novaSenha) {
		this.novaSenha = novaSenha;
	}
}
